'************************************************************************************
' Copyright © 2003-2005 Kathleen Dollard
'
' This software is provided 'as-is', without any express or implied warranty. In no 
' event will the author be held liable for any damages arising from the use of this
' software.
' 
' You may use this software for any purpose, including commercial applications, 
' and you may redistribute this software as part of application delivery: however, 
' this copyright notice may not be removed and you may not otherwise redistribute 
' this software directly other than providing a link to wwww.gendotnet.com. 
'
' You may alter this software to better server your needs (I'd like to hear about your 
' changes in order to make the software better). If you alter the softwre, you must  
' clearly mark it as altered and must not be misrepresented as the original software.
' nor wholly your original work.
'*************************************************************************************
Option Strict On
Option Explicit On 

Imports System

Namespace KADGen.Utility
   ' The purpose of this class is to allow assemblies to be reloaded. This is useful in RunProcess,
   ' BruteForce Generation, CodeDOM Generation, and potentially in support of programmer created 
   ' XSLT callbacks
   ' For information on what I'm doing,read Eric Gunnerson's article "AppDomainas and Dynamic Loading" May 17,2002 MSDN
   Public Class ExternalAssembly

#Region "Class level declarations"
      Private mAssemblyFileName As String
      Private mAsm As Reflection.Assembly
      Private mLoader As Loader
#End Region

#Region "Constructors"
      Public Sub New(ByVal assemblyFileName As String)
         Me.AssemblyFileName = assemblyFileName
      End Sub

#End Region

#Region "Public properties and methods"
      Public Property AssemblyFileName() As String
         Get
            Return mAssemblyFileName
         End Get
         Set(ByVal Value As String)
            mAssemblyFileName = Value
            Unload()
         End Set
      End Property

      'Public ReadOnly Property [Assembly]() As Reflection.Assembly
      '   Get
      '      If mAsm Is Nothing Then
      '         If Not AssemblyFileName Is Nothing AndAlso AssemblyFileName.Trim.Length > 0 Then
      '            mLoader = New Loader(AssemblyFileName)
      '            mAsm = mLoader.LoadAssembly(AssemblyFileName)
      '            'mAsm = Reflection.Assembly.LoadFile(AssemblyFileName)
      '            'ElseIf Not assemblyName Is Nothing AndAlso assemblyName.Trim.Length > 0 Then
      '            '   asm = Reflection.Assembly.Load(assemblyName)
      '            'Else
      '            '   asm = callingType.Assembly
      '         End If
      '      End If
      '      Return Nothing
      '   End Get
      'End Property

      Public Sub Unload()
         mAsm = Nothing
         If Not mLoader Is Nothing Then
            mLoader.Unload()
         End If
      End Sub
#End Region

      '#Region "Private properties and methods"
      '#End Region

   End Class

   Public Class Loader
#Region "Class level declarations"
      Private mAppDomain As System.AppDomain
      Private mRemoteLoader As Utility.ExternalAssemblyRemoteLoader
#End Region

#Region "Constructors"
      Public Sub New(ByVal assemblyFileName As String)
         Dim setup As New System.AppDomainSetup
         Dim dirName As String
         dirName = IO.Path.GetDirectoryName(assemblyFileName)
         'setup.PrivateBinPath = "C:\Current Projects\CodeGen\Tools\Utility\bin"
         setup.PrivateBinPathProbe = AppDomain.CurrentDomain.BaseDirectory & ";" & dirName & ";..\bin"
         'setup.ApplicationBase = dirName
         'setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
         'setup.PrivateBinPath = dirName
         'setup.PrivateBinPathProbe = dirName
         setup.ApplicationName = "CodeGenerationDevUI.exe"
         setup.ShadowCopyDirectories = dirName
         mAppDomain = AppDomain.CreateDomain("Extensions", Nothing, setup)
         mRemoteLoader = CType(mAppDomain.CreateInstanceAndUnwrap( _
                     Me.GetType.Assembly.FullName, "KADGen.Utility.ExternalAssemblyRemoteLoader"), _
                     Utility.ExternalAssemblyRemoteLoader)
      End Sub
#End Region


#Region "Public properties and methods"
      'Public Function LoadAssembly(ByVal fullName As String) As Reflection.Assembly
      '   'Dim asm2 As Reflection.Assembly
      '   'asm2 = Reflection.Assembly.LoadFile(fullName)
      '   Dim asms() As Reflection.Assembly
      '   Dim fileName As String
      '   mRemoteLoader.LoadAssembly(fullName)
      '   asms = mAppDomain.GetAssemblies
      '   For Each asm As Reflection.Assembly In asms
      '      If asm.GetName.Name = fileName Then
      '         Return asm
      '      End If
      '   Next
      '   Return Nothing
      'End Function

      Public Sub Unload()
         If Not mAppDomain Is Nothing Then
            AppDomain.Unload(mAppDomain)
            mAppDomain = Nothing
         End If
      End Sub

#End Region
   End Class
End Namespace